package com.my.collection.expiration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * Created by ZhongGang
 * at 2018/7/24 17:38
 */
public class PooledObject<V> implements Delayed {
    private static final Logger LOGGER = LoggerFactory.getLogger(PooledObject.class);

    private long creationTime;//创建时间
    private long keepLiveTime;//存活时间
    private TimeUnit keepLiveTimeUnit = TimeUnit.SECONDS;//存活时间单位
    private V v;

    public PooledObject(V v, long keepLiveTime) {
        this.creationTime = System.currentTimeMillis();
        this.v = v;
        this.keepLiveTime = keepLiveTime;
    }

    public PooledObject(V v, long keepLiveTime, TimeUnit keepLiveTimeUnit) {
        this.creationTime = System.currentTimeMillis();
        this.keepLiveTime = keepLiveTime;
        this.keepLiveTimeUnit = keepLiveTimeUnit;
        this.v = v;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        long creationTime = unit.convert(this.creationTime, TimeUnit.MILLISECONDS);
        long keppLiveTime = unit.convert(this.keepLiveTime, this.keepLiveTimeUnit);
        long currentTime = unit.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        return creationTime + keppLiveTime - currentTime;
    }

    @Override
    public int compareTo(Delayed o) {
        long first = this.getDelay(TimeUnit.NANOSECONDS);
        long second = o.getDelay(TimeUnit.NANOSECONDS);
        return Long.compare(first, second);
    }

    public static void main(String[] args) throws Exception {
        DelayQueue<PooledObject<Integer>> delayQueue = new DelayQueue<>();
        for (int i = 1; i < 11; i++) {
            delayQueue.offer(new PooledObject<>(i, 11 - i));
        }

        while (true) {
            PooledObject<Integer> pooledObject = delayQueue.take();
            LOGGER.info("{}", pooledObject.v);
        }
    }
}
